package com.iflytek.demo.ability.iat;

import ohos.media.audio.AudioCapturer;
import ohos.media.audio.AudioCapturerInfo;
import ohos.media.audio.AudioStreamInfo;

/**
 * 鸿蒙 录音功能
 *
 * @author zhhuang10
 * @date 2020/10/30
 */
public class AudioRecorder {
    // 音频输入 : 麦克风
    // 采用频率 16000
    private final static int AUDIO_SAMPLE_RATE = 16000;
    // 缓冲区字节大小
    private int bufferSizeInBytes = 0;
    // 录音对象
    private AudioCapturer audioCapturer;
    // 录音结束回调
    private FinishCallBack finishCallBack;

    /**
     * 创建默认的录音对象
     */
    public void initConfig() {

        if (audioCapturer != null && audioCapturer.getState() != AudioCapturer.State.STATE_STOPPED) {
            audioCapturer.release();
        }
        audioCapturer = null;
        AudioStreamInfo audioStreamInfo = new AudioStreamInfo.Builder()
                // 音频采样率 16000
                .sampleRate(AUDIO_SAMPLE_RATE)
                // 录音数据格式 16-bit PCM
                .encodingFormat(AudioStreamInfo.EncodingFormat.ENCODING_PCM_16BIT)
                // 声道设置 单声道
                .channelMask(AudioStreamInfo.ChannelMask.CHANNEL_IN_MONO)
                .build();
        AudioCapturerInfo audioCapturerInfo = new AudioCapturerInfo.Builder()
                .audioStreamInfo(audioStreamInfo)
                // 录音源
                .audioInputSource(AudioCapturerInfo.AudioInputSource.AUDIO_INPUT_SOURCE_MIC)
                .build();
        audioCapturer = new AudioCapturer(audioCapturerInfo);
        bufferSizeInBytes = AudioCapturer.getMinBufferSize(AUDIO_SAMPLE_RATE, 1, 2);
    }


    /**
     * 开始录音
     *
     * @param listener 音频流的监听回调
     */
    public void startRecord(final RecordListener listener) {
        if (audioCapturer.getState() == AudioCapturer.State.STATE_UNINITIALIZED) {
            throw new IllegalStateException("AudioCapturer need init first");
        }
        if (isRecording()) {
            throw new IllegalStateException("AudioCapturer is in recording now");
        }
        // 开始录音
        audioCapturer.start();
        final byte[] audioData = new byte[bufferSizeInBytes];
        while (isRecording()) {
            int size = audioCapturer.read(audioData, 0, bufferSizeInBytes);
            if (size > 0 && listener != null) {
                if (size == bufferSizeInBytes) {
                    // 通过回掉回传录音数据
                    listener.onRead(audioData);
                } else {
                    // 通过回掉回传录音数据
                    final byte[] copy = new byte[size];
                    System.arraycopy(audioData, 0, copy, 0, size);
                    listener.onRead(copy);
                }
            }
        }
        if (finishCallBack != null) {
            finishCallBack.onFinish();
        }
    }

    public void setFinishCallBack(FinishCallBack finishCallBack) {
        this.finishCallBack = finishCallBack;
    }

    /**
     * 停止录音
     */
    public synchronized void stopRecord() {
        if (isRecording()) {
            audioCapturer.stop();
        }
    }

    /**
     * 释放资源
     */
    public synchronized void release() {
        if (audioCapturer != null) {
            audioCapturer.release();
            audioCapturer = null;
        }
    }

    /**
     * 是否正在录音
     */
    public synchronized boolean isRecording() {
        return audioCapturer != null && audioCapturer.getState() == AudioCapturer.State.STATE_RECORDING;
    }

    /**
     * 录音数据监听
     */
    public interface RecordListener {

        /**
         * 接收录音数据
         *
         * @param data data
         */
        void onRead(final byte[] data);
    }

    /**
     * 录音结束监听
     */
    public interface FinishCallBack {

        void onFinish();
    }
}